package framework.base;

import lombok.Getter;

import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * <p>依据查询对象查找数据，找不到则添加，找到则更新</p>
 * <p>此对象方法使用查询后更新方式，适用于简单修改，不适用于高性能要求场景</p>
 * <p>若有高性能操作需要，请另行实现</p>
 *
 * @param <S> 服务对象类型
 * @param <T> 服务实体对象类型
 * @param <K> 服务实体主键类型
 */
public class UpdateOrInsert<S extends BaseService<T, K>, T, K> {
    @Getter
    private final S service;

    public UpdateOrInsert(S service) {
        this.service = service;
    }

    /**
     * 依据修改对像更新数据，找不到则添加，找到则依据主键更新
     *
     * @return
     */
    public Integer updateByPK(T param) {
        if (getService().existsByPK(param)) {
            return getService().update(param);
        }
        return getService().add(param);
    }

    /**
     * 依据查询对象查找数据，找不到则添加，找到则更新
     *
     * @param param 查询对象
     * @param query 查询条件
     * @return
     */
    public Integer update(T param, Function<T, T> query) {
        return update(param, query, null);
    }

    /**
     * 依据查询对象查找数据，找不到则添加，找到则更新, 允许设置查询条件和按旧对象修改更新对象
     *
     * @param param  查询对象
     * @param query  查询条件
     * @param modify 修改条件
     * @return
     */
    public Integer update(T param, Function<T, T> query, BiConsumer<T, T> modify) {
        T where = query.apply(param);
        T oldObject = getService().loadPrimaryKeyFirst(where);
        if (oldObject != null) {
            if (modify != null) {
                modify.accept(param, oldObject);
            }
            return getService().update(param);
        }
        return getService().add(param);
    }
}
